package com.basic.nio;

import org.junit.jupiter.api.Test;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * @Author: wisdom
 * @Date: 2024/3/31  9:28 AM
 * @Description:
 */
public class ChannelTest {


    /**
     * transferFrom 原通道数据复制到目标通道
     * @throws IOException
     */
    @Test
    public void transferTo() throws IOException {
        FileInputStream fis = new FileInputStream("data.txt");
        FileChannel isChannel = fis.getChannel();
        FileOutputStream fos = new FileOutputStream("data4.txt");
        FileChannel osChannel = fos.getChannel();

        isChannel.transferTo(isChannel.position(),isChannel.size(),osChannel);

        isChannel.close();
        osChannel.close();
    }

    /**
     * transferFrom 从目标通道去复制原通道数据
     * @throws IOException
     */
    @Test
    public void transferFrom() throws IOException {
        FileInputStream fis = new FileInputStream("data.txt");
        FileChannel isChannel = fis.getChannel();
        FileOutputStream fos = new FileOutputStream("data3.txt");
        FileChannel osChannel = fos.getChannel();

        osChannel.transferFrom(isChannel,isChannel.position(),isChannel.size());

        isChannel.close();
        osChannel.close();
    }
    @Test
    public void mutBuffer() throws IOException {
        FileInputStream fis = new FileInputStream("data.txt");
        FileChannel isChannel = fis.getChannel();
        FileOutputStream fos = new FileOutputStream("data2.txt");
        FileChannel osChannel = fos.getChannel();
        //定义多个缓冲区做数据分散
        ByteBuffer buffer = ByteBuffer.allocate(4);
        ByteBuffer buffer2 = ByteBuffer.allocate(1024);
        ByteBuffer[] buffers = {buffer,buffer2};
        //通道读到各个缓冲区
        isChannel.read(buffers);
        for (ByteBuffer byteBuffer : buffers) {
            byteBuffer.flip();
            System.out.println(new String(byteBuffer.array(),0,byteBuffer.remaining()));
        }
        //聚集写到通道
        osChannel.write(buffers);
        isChannel.close();
        osChannel.close();
    }

    @Test
    public void fileCopyChannel() throws IOException {
        FileInputStream fis = new FileInputStream("long.jpg");
        FileChannel isChannel = fis.getChannel();
        FileOutputStream fos = new FileOutputStream("long2.jpg");
        FileChannel osChannel = fos.getChannel();

        //定义缓冲区 注意容量大小
        ByteBuffer buf = ByteBuffer.allocate(1024);
        while (true){
            //必须先清空缓冲区再写入数据到缓冲区
            buf.clear();
            int read = isChannel.read(buf);
            if(read == -1){
                break;
            }
            //读取完数据，缓冲区切换成可读模式
            buf.flip();
            osChannel.write(buf);
        }
        osChannel.close();
        isChannel.close();
    }

    @Test
    public void fileReadChannel() throws IOException {
        FileInputStream fis = new FileInputStream("data.txt");
        FileChannel channel = fis.getChannel();

        //定义缓冲区 注意容量大小
        ByteBuffer buf = ByteBuffer.allocate(1024);
        //数据读到缓冲区
        channel.read(buf);
        buf.flip();
        System.out.println(new String(buf.array(),0,buf.remaining()));
        channel.close();
    }

    @Test
    public void fileWriteChannel() throws IOException {
        FileOutputStream fos = new FileOutputStream("data.txt");
        //获取到文件通道
        FileChannel channel = fos.getChannel();
        //定义缓冲区 注意容量大小
        ByteBuffer buf = ByteBuffer.allocate(1024);
        String content = "hello,黑马程序员";
        buf.put(content.getBytes());
        //转成写模式 position重置，limit到原position位置
        buf.flip();
        //文件输出
        channel.write(buf);
        //通道关闭
        channel.close();
    }
}
